home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Comm
/
AmiTCP30b2.lha
/
src
/
appl
/
napsaterm
/
display.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-14
|
11KB
|
527 lines
RCS_ID_C "$Id: display.c,v 3.2 1994/05/11 16:48:06 ppessi Exp $";
/*
* display.c --- generic display routines for niftyterm
*
* Copyright 1989, Chris Newman
* All Rights Reserved
* Permission is granted ot copy, modify, and use this as long
* as this notice remains intact. This is a nifty program.
*
* DISCLAIMER: the author (and maintainer) of this program is not responsible
* for any damage or other problems caused by it.
*
* $Author: ppessi $ $Revision: 3.2 $ $Date: 1994/05/11 16:48:06 $
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "nifty.h"
#include "display.h"
#include "dispmacros.h"
#include "napsaprefs.h"
/*
* display specific routines called:
* dsscroll(), dsinvert(), dsstyle(), dsputs()
* dssetfont()
*/
/* global display structure */
struct nifty_display disp;
/* global settings in emulate.c needed for soft reset */
extern int vt100_yucky_wrap_mode;
/*
* allocate the display buffers
*/
void allocate_display(int width, int height)
{
disp.buf = calloc((sizeof(char) * (width + 1) * height), 1);
disp.sbuf = calloc((sizeof(short) * (width + 1) * height), 1);
disp.tabstops = calloc((sizeof (char) * width), 1);
disp.maxwidth = width;
disp.maxheight = height;
disp.bufwidth = width + 1;
if (disp.buf == NULL || disp.sbuf == NULL || disp.tabstops == NULL) {
fatalError(MEMORY_ERROR_MSG);
}
}
/*
* Free up memory allocated for display
*/
void free_display(void)
{
if (disp.buf)
free(disp.buf), disp.buf = NULL;
if (disp.sbuf)
free(disp.sbuf), disp.sbuf = NULL;
if (disp.tabstops)
free(disp.tabstops), disp.tabstops = NULL;
}
/*
* clear out the display
*/
void clear_display(void)
{
register int y;
for (y = 0; y < disp.maxheight; y++) {
disp.plines[y] = disp.buf+y*disp.bufwidth;
disp.pstyles[y] = disp.sbuf+y*disp.bufwidth;
STYLEFLAG(y) = 0;
LINELENST(y) = 0;
}
disp.curx = disp.cury = 0;
}
/*
* clear out the tab stops
*/
void clear_tabstops(void)
{
register int i;
for (i=0; i<disp.maxwidth; i++)
disp.tabstops[i] = 0;
}
/*
* initialize tabstops to 8 characters
*/
void init_tabstops(void)
{
register int i;
for (i=0; i<disp.maxwidth; i++)
disp.tabstops[i] = (i % 8) == 0;
}
/*
* reset the display
*/
void reset_display(int soft)
{
if (!soft) {
clear_display();
disp.scrolldefault = 1;
}
(void) dsstyle(STYLESOFF);
disp.visual = np.visual;
disp.insert = disp.origin = disp.scrolltop = disp.savex = disp.savey = 0;
disp.scrollbot = soft ? disp.winheight - 1 : disp.maxheight;
disp.scrollskip = disp.scrolldefault;
disp.wrap = 1;
init_tabstops();
}
/*
* move cursor to x, y
*/
void dscursorto(int x, int y)
{
int wflag;
if (disp.origin) {
y += disp.scrolltop;
MAXBOUNDCK(y, disp.scrollbot);
} else
SLIMITCK(y, disp.winheight);
if (disp.cury != y)
dssetfont(disp.style, disp.cury = y);
wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
disp.curx = SLIMIT(x, disp.winwidth/wflag);
}
/*
* return size of the current window
*/
void dsgetsize(int *x, int *y)
{
*x = disp.winwidth;
*y = disp.winheight;
}
/*
* get cursor position
*/
void dsgetcursor(int *x, int *y)
{
*x = disp.curx;
*y = disp.cury;
}
/*
* display style changes
*/
int dsstyle(int style)
{
switch (style) {
case BOLD1: /* bold on */
disp.style |= BOLD;
break;
case BOLD0: /* bold off */
disp.style &= ~BOLD;
break;
case ITALIC1: /* italic on */
disp.style |= ITALIC;
break;
case ITALIC0: /* italic off */
disp.style &= ~ITALIC;
break;
case UNDERLINE1: /* underline on */
disp.style |= UNDERLINE;
break;
case UNDERLINE0: /* underline off */
disp.style &= ~UNDERLINE;
break;
case INVERSE1: /* inverse on */
disp.style |= INVERSE;
break;
case INVERSE0: /* inverse off */
disp.style &= ~INVERSE;
break;
case BLINK1:
disp.style |= FLASH;
break;
case BLINK0:
disp.style &= ~FLASH;
break;
case ALTERNATE1:
disp.style |= ALTERNATE;
break;
case ALTERNATE0:
disp.style &= ~ALTERNATE;
break;
case STYLESOFF: /* turn off all */
disp.style = 0;
break;
case SAVE_STYLE: /* save the style */
disp.savestyle = disp.style;
break;
case RESTORE_STYLE: /* restore the saved style */
disp.style = disp.savestyle;
break;
case DWIDTH1: /* double width */
if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == (DOUBLE1 | DOUBLE2))
break;
STYLEFLAG(disp.cury) |= DOUBLE1 | DOUBLE2;
redraw_line(disp.cury);
break;
case DWIDTHTOP:/* double width/height top */
if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == DOUBLE1)
break;
STYLEFLAG(disp.cury) &= ~DOUBLE2;
STYLEFLAG(disp.cury) |= DOUBLE1;
redraw_line(disp.cury);
break;
case DWIDTHBOT: /* double width/height bottom */
if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == DOUBLE2)
break;
STYLEFLAG(disp.cury) &= ~DOUBLE1;
STYLEFLAG(disp.cury) |= DOUBLE2;
redraw_line(disp.cury);
break;
case DWIDTH0: /* single width, single height */
if ((STYLEFLAG(disp.cury) & DOUBLE_MASK) == 0)
break;
STYLEFLAG(disp.cury) &= ~DOUBLE_MASK;
redraw_line(disp.cury);
break;
default: /* style unavailable */
return -1;
}
dssetfont(disp.style, disp.cury);
return 0;
}
/*
* check if cursor can move down without scrolling, and move cursor if it can.
*/
int dscheckdown(void)
{
return (disp.cury < disp.scrollbot ? ++disp.cury : 0);
}
/*
* move the cursor
*/
void dscursormove(int move, int n)
{
int wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
if (n<1) n=1;
switch (move) {
case CURSOR_UP: case REVERSE_INDEX:
disp.cury -= n;
if (disp.cury < disp.scrolltop) {
if (move == REVERSE_INDEX) {
dsscroll(disp.scrolltop,disp.scrollbot - disp.scrolltop + 1,disp.cury - disp.scrolltop);
}
disp.cury = disp.scrolltop;
}
break;
case CURSOR_RIGHT:
disp.curx += n;
SLIMITCK(disp.curx, disp.winwidth/wflag);
break;
case CURSOR_LEFT:
disp.curx -= n;
MINBOUNDCK(disp.curx, 0);
break;
case DOWN1_AND_SCROLL:
{
int scrolltop = disp.scrolltop;
int scrollheight = disp.scrollbot - scrolltop;
int scrollsize;
if (disp.scrollskip > n)
n = disp.scrollskip;
if (disp.cury > disp.scrollbot) {
scrollheight = disp.winheight;
scrolltop = 0;
}
if (n > (scrollsize = (scrollheight >> 1)))
n = scrollsize ? scrollsize : 1;
disp.cury -= n-1;
dsscroll(scrolltop, scrollheight + 1, n);
}
break;
case CURSOR_DOWN: case NEXT_LINE: case INDEX:
if (disp.cury <= disp.scrollbot
&& (disp.cury+=n) > disp.scrollbot) {
if (move == CURSOR_DOWN) {
disp.cury = disp.scrollbot;
} else {
dsscroll(disp.scrolltop,
disp.scrollbot - disp.scrolltop + 1,
disp.cury - disp.scrollbot + disp.scrollskip - 1);
disp.cury = disp.scrollbot - disp.scrollskip + 1;
}
} else if (disp.cury > disp.scrollbot
&& (disp.cury+=n) > disp.winheight-1) {
if (move == CURSOR_DOWN) {
disp.cury = disp.winheight-1;
} else {
dsscroll(0, disp.winheight,
disp.cury - disp.winheight + disp.scrollskip);
disp.cury = disp.winheight - disp.scrollskip;
}
}
if (move != NEXT_LINE)
break;
/* fall through */
case BEGIN_LINE:
disp.curx = 0;
break;
case END_LINE:
disp.curx = disp.winwidth/wflag-1;
break;
case BOTTOM_HOME:
disp.curx = 0;
disp.cury = disp.winheight-1;
break;
case SAVE_CURSOR:
disp.savex = disp.curx;
disp.savey = disp.cury;
(void) dsstyle(SAVE_STYLE);
break;
case RESTORE_CURSOR:
disp.curx = disp.savex;
disp.cury = disp.savey;
(void) dsstyle(RESTORE_STYLE);
break;
case INSERT_LINE:
dsscroll(disp.cury, disp.scrollbot-disp.cury+1, -n);
break;
case DELETE_LINE:
dsscroll(disp.cury, disp.scrollbot-disp.cury+1, n);
break;
case INSERT_CHAR: {
char insertme[MAXWIDTH];
int temp;
disp.insert++;
insertme[SLIMIT(n,MAXWIDTH)] = '\0';
for (temp = n; --temp >= 0; insertme[temp] = ' ');
temp = disp.curx;
dsputs(insertme);
disp.curx = temp;
disp.insert--;
}
break;
case TAB_STOP:
if (n > 1) {
while (disp.curx < disp.winwidth/wflag-1 && ++disp.curx % n);
} else {
while (disp.curx < disp.winwidth/wflag-1 &&
!disp.tabstops[++disp.curx]);
}
break;
}
dssetfont(disp.style, disp.cury);
}
/*
* miscellaneous terminal functions
*/
void dsfunction(int what)
{
int wflag = STYLEFLAG(disp.cury) & DOUBLE_MASK ? 2 : 1;
switch(what) {
case ERASETO_EOS:
if (disp.cury < disp.winheight - 1)
dsclear(0, disp.cury + 1,
disp.winwidth / wflag - 1, disp.winheight - 1);
/* fall through */
case ERASETO_EOL:
if (disp.curx < disp.winwidth/wflag-1)
dsclear(disp.curx, disp.cury,
disp.winwidth / wflag - 1, disp.cury);
break;
case ERASETO_SOS:
if (disp.cury)
dsclear(0, 0, disp.winwidth/wflag-1, disp.cury-1);
/* fall through */
case ERASETO_SOL:
if (disp.curx)
dsclear(0, disp.cury, disp.curx, disp.cury);
break;
case ERASE_LINE:
dsclear(0, disp.cury, disp.winwidth/wflag-1, disp.cury);
break;
case RESET_DISPLAY:
reset_display(1);
break;
case SCROLL_UP:
dsscroll(disp.scrolltop, disp.scrollbot - disp.scrolltop + 1, 1);
break;
case SCROLL_DOWN:
dsscroll(disp.scrolltop, disp.scrollbot - disp.scrolltop + 1, -1);
break;
case ORIGIN_ON:
disp.origin = 1;
break;
case ORIGIN_OFF:
disp.origin = 0;
break;
case BLOCK_CURSOR:
disp.visual |= CUR_BLOCK;
break;
case UNDERLINE_CURSOR:
disp.visual &= ~CUR_BLOCK;
break;
case INVISIBLE_CURSOR:
disp.visual |= CUR_INVISIBLE;
break;
case VISIBLE_CURSOR:
disp.visual &= ~CUR_INVISIBLE;
break;
case WRAP_ON:
disp.wrap = 1;
break;
case WRAP_OFF:
disp.wrap = 0;
break;
case INSERT_ON:
disp.insert = 1;
break;
case INSERT_OFF:
disp.insert = 0;
break;
case SET_TAB:
disp.tabstops[disp.curx] = 1;
break;
case CLEAR_TAB:
disp.tabstops[disp.curx] = 0;
break;
case CLEAR_ALL_TABS:
clear_tabstops();
break;
}
dssetfont(disp.style, disp.cury);
}
/*
* set the scrolling region
*/
void dssetscroll(int top, int bot)
{
if (top)
top--;
if (bot)
bot--;
if (bot - top < 1)
disp.scrolltop = 0, disp.scrollbot = disp.winheight - 1;
else {
if (top >= disp.winheight)
top = 0;
if (bot >= disp.winheight)
bot = disp.winheight-1;
disp.scrolltop = top;
disp.scrollbot = bot;
}
disp.curx = 0;
if (disp.origin)
disp.cury = disp.scrolltop;
else
disp.cury = 0;
if (disp.scrolltop || disp.scrollbot < disp.winheight - 1)
disp.scrollskip = 1;
else
disp.scrollskip = disp.scrolldefault;
dssetfont(disp.style, disp.cury);
}
/*
* Set cursor map to use
*/
void dskeyboard(int cmd, int val)
{
switch (cmd) {
case DS_CURSORMODE:
case DS_KEYPADAPPMODE:
np.cursormap = val;
break;
}
}